package me.zhangyifeng.blog.web.controller.front;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageInfo;
import me.zhangyifeng.blog.model.domain.ArticleCustom;
import me.zhangyifeng.blog.model.domain.Log;
import me.zhangyifeng.blog.model.domain.User;
import me.zhangyifeng.blog.model.dto.JsonResult;
import me.zhangyifeng.blog.model.dto.LogConstant;
import me.zhangyifeng.blog.model.dto.MaydayConst;
import me.zhangyifeng.blog.model.enums.MaydayEnums;
import me.zhangyifeng.blog.model.enums.PostType;
import me.zhangyifeng.blog.service.ArticleService;
import me.zhangyifeng.blog.service.AttachmentService;
import me.zhangyifeng.blog.service.LogService;
import me.zhangyifeng.blog.service.UserService;
import me.zhangyifeng.blog.web.controller.admin.BaseController;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;

/**
 * 用户前端控制器
 */
@Controller
@RequestMapping(value = "/user")
public class UserFrontController extends BaseController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private ArticleService articleService;
    
    @Autowired
    private AttachmentService attachmentService;
    
    @Autowired
    private HttpServletRequest request;
    
    @Autowired
    private LogService logService;
    
    /**
     * 跳转到用户登录页面
     */
    @GetMapping("/login")
    public String login(HttpSession session) {
        User user = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
        // 如果用户已经登录，跳转到个人中心
        if (user != null) {
            return "redirect:/user/dashboard";
        }
        return "user/user_login";
    }
    
    /**
     * 跳转到用户注册页面
     */
    @GetMapping("/register")
    public String register(HttpSession session) {
        User user = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
        // 如果用户已经登录，跳转到个人中心
        if (user != null) {
            return "redirect:/user/dashboard";
        }
        return "user/user_register";
    }
    
    /**
     * 用户注册提交
     */
    @PostMapping(value = "register")
    @ResponseBody
    public JsonResult registerSubmit(@RequestParam(value = "userName") String userName,
                                    @RequestParam(value = "userPwd") String userPwd,
                                    @RequestParam(value = "userEmail") String userEmail,
                                    @RequestParam(value = "userDisplayName") String userDisplayName) {
        // 校验
        if (StringUtils.isBlank(userName) || StringUtils.isBlank(userPwd) || 
            StringUtils.isBlank(userEmail) || StringUtils.isBlank(userDisplayName)) {
            return new JsonResult(MaydayEnums.ERROR.isFlag(), "请填写完整信息");
        }
        
        // 用户名唯一性检查
        try {
            User checkUser = userService.findByUserName(userName);
            if (checkUser != null) {
                return new JsonResult(MaydayEnums.ERROR.isFlag(), "该用户名已存在");
            }
            
            // 创建新用户
            User user = new User();
            user.setUserName(userName);
            user.setUserPwd(SecureUtil.md5(userPwd));
            user.setUserEmail(userEmail);
            user.setUserDisplayName(userDisplayName);
            user.setLoginEnable("false");
            user.setLoginError(0);
            user.setLoginLastTime(DateUtil.date());
            
            userService.save(user);
            
            // 记录日志
            logService.save(new Log(LogConstant.REGISTER, LogConstant.REGISTER_SUCCESS, 
                ServletUtil.getClientIP(request), DateUtil.date()));
            
            return new JsonResult(MaydayEnums.OPERATION_SUCCESS.isFlag(), "注册成功，请登录！");
        } catch (Exception e) {
            log.error("用户注册失败：{}", e.getMessage());
            return new JsonResult(MaydayEnums.ERROR.isFlag(), "注册失败，请稍后重试！");
        }
    }
    
    /**
     * 用户登录提交
     */
    @PostMapping(value = "login")
    @ResponseBody
    public JsonResult loginSubmit(@RequestParam(value = "userName") String userName,
                                @RequestParam(value = "userPwd") String userPwd,
                                HttpSession session) {
        try {
            // 验证用户名密码
            User user = userService.getByNameAndPwd(userName, SecureUtil.md5(userPwd));
            
            if (user != null) {
                // 记录最后登录时间
                userService.updateLoginLastTime(DateUtil.date(), user.getUserId());
                
                // 将用户信息存入session
                session.setAttribute(MaydayConst.USER_SESSION_KEY, user);
                
                // 添加登录日志
                logService.save(new Log(LogConstant.LOGIN, LogConstant.LOGIN_SUCCES, 
                    ServletUtil.getClientIP(request), DateUtil.date()));
                
                return new JsonResult(MaydayEnums.OPERATION_SUCCESS.isFlag(), "登录成功！");
            } else {
                return new JsonResult(MaydayEnums.ERROR.isFlag(), "用户名或密码错误！");
            }
        } catch (Exception e) {
            log.error("用户登录失败：{}", e.getMessage());
            return new JsonResult(MaydayEnums.ERROR.isFlag(), "登录失败，请稍后重试！");
        }
    }
    
    /**
     * 用户仪表板
     */
    @GetMapping("/dashboard")
    public String dashboard(Model model, HttpSession session) {
        User user = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
        
        // 检查用户是否登录
        if (user == null) {
            return "redirect:/user/login";
        }
        
        // 查询用户文章数量
        Integer articleCount = articleService.countByStatusAndUserId(null, PostType.POST_TYPE_POST.getValue(), user.getUserId());
        model.addAttribute("articleCount", articleCount);
        
        // 查询用户最新的5篇文章
        ArticleCustom params = new ArticleCustom();
        params.setArticlePost(PostType.POST_TYPE_POST.getValue());
        params.setUserId(user.getUserId());
        PageInfo<ArticleCustom> pageInfo = articleService.findPageArticle(1, 5, params);
        model.addAttribute("articles", pageInfo.getList());
        
        return "user/user_dashboard";
    }
    
    /**
     * 用户文章列表
     */
    @GetMapping("/articles")
    public String articles(Model model, HttpSession session,
                          @RequestParam(value = "page", defaultValue = "1") int page,
                          @RequestParam(value = "limit", defaultValue = "10") int limit) {
        User user = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
        
        // 检查用户是否登录
        if (user == null) {
            return "redirect:/user/login";
        }
        
        // 查询用户的文章列表
        ArticleCustom params = new ArticleCustom();
        params.setArticlePost(PostType.POST_TYPE_POST.getValue());
        params.setUserId(user.getUserId());
        PageInfo<ArticleCustom> pageInfo = articleService.findPageArticle(page, limit, params);
        model.addAttribute("articles", pageInfo);
        
        return "user/user_articles";
    }
    
    /**
     * 用户个人信息页
     */
    @GetMapping("/profile")
    public String profile(Model model, HttpSession session) {
        User user = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
        
        // 检查用户是否登录
        if (user == null) {
            return "redirect:/user/login";
        }
        
        model.addAttribute("user", user);
        return "user/user_profile";
    }
    
    /**
     * 修改个人资料
     */
    @PostMapping(value = "updateProfile")
    @ResponseBody
    public JsonResult updateProfile(User user, HttpSession session) {
        try {
            User currentUser = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
            if (currentUser == null) {
                return new JsonResult(MaydayEnums.ERROR.isFlag(), "请先登录");
            }
            
            // 只允许修改自己的信息
            if (!currentUser.getUserId().equals(user.getUserId())) {
                return new JsonResult(MaydayEnums.ERROR.isFlag(), "只能修改自己的信息");
            }
            
            // 保留原密码
            user.setUserPwd(currentUser.getUserPwd());
            userService.updateDatum(user);
            
            // 更新session中的用户信息
            session.setAttribute(MaydayConst.USER_SESSION_KEY, userService.findByUserId(user.getUserId()));
            
            return new JsonResult(MaydayEnums.PRESERVE_SUCCESS.isFlag(), "保存成功");
        } catch (Exception e) {
            log.error("修改资料失败：{}", e.getMessage());
            return new JsonResult(MaydayEnums.ERROR.isFlag(), "修改失败");
        }
    }
    
    /**
     * 修改密码
     */
    @PostMapping(value = "updatePwd")
    @ResponseBody
    public JsonResult updatePwd(@RequestParam(value = "formerlyPwd") String formerlyPwd,
                               @RequestParam(value = "newPwd") String newPwd,
                               @RequestParam(value = "confirmPwd") String confirmPwd,
                               HttpSession session) {
        if (StringUtils.isBlank(formerlyPwd) || StringUtils.isBlank(newPwd) || StringUtils.isBlank(confirmPwd)) {
            return new JsonResult(MaydayEnums.OPERATION_ERROR.isFlag(), "请填写完整信息");
        }
        
        if (!newPwd.equals(confirmPwd)) {
            return new JsonResult(MaydayEnums.OPERATION_ERROR.isFlag(), "两次密码不一致");
        }
        
        try {
            User currentUser = (User) session.getAttribute(MaydayConst.USER_SESSION_KEY);
            if (currentUser == null) {
                return new JsonResult(MaydayEnums.ERROR.isFlag(), "请先登录");
            }
            
            User user = userService.findByUserIdAndUserPwd(currentUser.getUserId(), SecureUtil.md5(formerlyPwd));
            if (user != null) {
                user.setUserPwd(SecureUtil.md5(confirmPwd));
                userService.updateDatum(user);
                
                // 修改密码后，需要重新登录
                session.invalidate();
                
                return new JsonResult(MaydayEnums.OPERATION_SUCCESS.isFlag(), "修改密码成功，请重新登录");
            } else {
                return new JsonResult(MaydayEnums.OPERATION_ERROR.isFlag(), "原密码错误");
            }
        } catch (Exception e) {
            log.error("修改密码失败：{}", e.getMessage());
            return new JsonResult(MaydayEnums.ERROR.isFlag(), "修改密码失败");
        }
    }
    
    /**
     * 退出登录
     */
    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:/user/login";
    }
}
